home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / gemfxm15.lzh / WINDXMPL.LZH / WINDXMPL.C next >
C/C++ Source or Header  |  1990-05-27  |  12KB  |  427 lines

  1. /* tab expansion/compression should be set to 4 in your editor */
  2. /**************************************************************************
  3.  *
  4.  * WINDXMPL.C - Demo of handling an object tree in a window, with minimal
  5.  *                emulation of form_do processing. (And with a special demo
  6.  *                of editing a text field based on either a mouse click or
  7.  *                a menu selection; a strange feature someone asked for.)
  8.  *
  9.  *                This file demos many of the alternate AES bindings 
  10.  *                routines such as frmx_center and evnx_multi.
  11.  *************************************************************************/
  12.  
  13. #include <osbind.h>
  14. #include <gemfast.h> 
  15. #include "windxmpl.h"
  16.  
  17. #define WI_KIND     (SIZER+MOVER+CLOSER+NAME)
  18. #define NO_WINDOW    -1
  19.  
  20. #define TRUE  1
  21. #define FALSE 0
  22.  
  23. OBJECT    *menutree;
  24. OBJECT    *windtree;
  25.  
  26. int     wchar;
  27. int     hchar;
  28. int     wi_handle = NO_WINDOW;
  29. char    wi_name[] = " Window Demo ";
  30.  
  31. extern int    gl_apid;
  32.  
  33. /**************************************************************************
  34.  *
  35.  * prg_init - Standard GEM startup.
  36.  *
  37.  *************************************************************************/
  38.  
  39. prg_init()
  40. {
  41.     int  dmy;
  42.     
  43.     appl_init();
  44.     
  45.     if (!rsrc_load("WINDXMPL.RSC")) {
  46.         form_alert(1,"[1][ | Can't load RSC! | ][ Fatal ]");
  47.         appl_exit();
  48.         Pterm(1);
  49.     }
  50.  
  51.     graf_handle(&wchar, &hchar, &dmy, &dmy);    /* For window min sizes */
  52.  
  53.     rsrc_gaddr(R_TREE, MENUTREE, &menutree);
  54.     rsrc_gaddr(R_TREE, WINDTREE, &windtree);
  55.  
  56.     menu_bar(menutree, TRUE);
  57.  
  58.     graf_mouse(ARROW, 0L);      
  59. }
  60.  
  61. /**************************************************************************
  62.  *
  63.  * prg_exit - Standard GEM exit.
  64.  *
  65.  *************************************************************************/
  66.  
  67. prg_exit()
  68. {
  69.     w_close();
  70.     menu_bar(menutree, FALSE);
  71.     rsrc_free();
  72.     appl_exit();
  73.     Pterm(0);
  74. }
  75.  
  76. /**************************************************************************
  77.  *
  78.  * w_open - Create and open a window.
  79.  *    The display tree is centered, then the window is sized to hold it.
  80.  *
  81.  *************************************************************************/
  82.  
  83. w_open()
  84. {
  85.     GRECT    wrect;
  86.     GRECT    treerect;
  87.     
  88.     if (wi_handle != NO_WINDOW) {        /* if window is already open,      */
  89.         return wi_handle;                /* just return the handle.          */
  90.     }
  91.  
  92.     frmx_center(windtree, &treerect);    /* center tree, sizes in treerect */
  93.  
  94.     winx_calc(WC_BORDER, WI_KIND, treerect, &wrect); /* calc window fullsize */
  95.  
  96.     wi_handle = wind_create(WI_KIND, wrect);         /* create window      */
  97.  
  98.     if (wi_handle < 0) {
  99.         form_error(4);                        /* can't open another window  */
  100.         wi_handle = NO_WINDOW;
  101.     } else {
  102.         wind_set(wi_handle, WF_NAME, wi_name, 0L);    /* set window title   */
  103.         wind_open(wi_handle, wrect);                /* open window          */
  104.     }
  105.     
  106.     return wi_handle;
  107.  
  108. }
  109.  
  110. /**************************************************************************
  111.  *
  112.  * w_close - Close and delete a window.
  113.  *
  114.  *************************************************************************/
  115.  
  116. w_close()
  117. {
  118.     if (wi_handle != NO_WINDOW) {    /* only do close processing */
  119.         wind_close(wi_handle);        /* if the window is open!    */
  120.         wind_delete(wi_handle);
  121.         wi_handle = NO_WINDOW;
  122.     }
  123. }
  124.  
  125. /**************************************************************************
  126.  *
  127.  * do_redraw - Standard AES redraw handler for trees in windows.
  128.  *
  129.  *************************************************************************/
  130.  
  131. do_redraw(window, ptree, predrawrect)
  132.     register int      window;
  133.     register OBJECT   *ptree;
  134.     register GRECT      *predrawrect;
  135. {
  136.     register int      calltype;
  137.     register int      doneflag;
  138.     GRECT              t1;
  139.     GRECT              t2;
  140.  
  141. /*
  142.  * process the rectangle list for the window.  for each intersection of
  143.  * the area to be redrawn with a visible window rectangle, call objc_draw
  144.  * to draw that portion of the menu.
  145.  */
  146.  
  147.     wind_update(BEG_UPDATE);
  148.     
  149.     calltype = WF_FIRSTXYWH;
  150.     doneflag = FALSE;
  151.  
  152.     do    {
  153.         winx_get(window, calltype, &t1);
  154.         if (t1.g_w && t1.g_h) {
  155.             if (rc_intersect(predrawrect, &t1) && t1.g_w && t1.g_h) {
  156.                 objc_draw(ptree, R_TREE, MAX_DEPTH, t1);
  157.             }
  158.         } else {
  159.             doneflag = TRUE;
  160.         }
  161.         calltype = WF_NEXTXYWH;
  162.     } while (doneflag == FALSE);
  163.  
  164.     wind_update(END_UPDATE);
  165. }
  166.  
  167. /**************************************************************************
  168.  *
  169.  * send_edmsg - Send a message to ourselves to edit the window field.
  170.  *    The message looks exactly like a normal MN_SELECTED.
  171.  *    This allows us to re-schedule the edit function after topping our 
  172.  *    window, in case the user picks the EDIT menu item while an ACC
  173.  *    window is topped.
  174.  *
  175.  *************************************************************************/
  176.  
  177. send_edmsg()
  178. {
  179.     static int    edmsg[8] = {MN_SELECTED, 0, 0, MENUFILE, MENUEDFN};
  180.     
  181.     edmsg[1] = gl_apid;
  182.     appl_write(gl_apid, 16, edmsg);
  183. }
  184.  
  185. /**************************************************************************
  186.  *
  187.  * hndl_message - Standard message handling code.
  188.  *
  189.  *************************************************************************/
  190.  
  191. hndl_message(msgbuf)
  192.     register int    *msgbuf;
  193. {
  194.     int             dmy;
  195.     int             top_window;
  196.     register OBJECT *ptree = windtree;
  197.     GRECT            t1, t2;
  198.  
  199.     switch (msgbuf[0]) {
  200.             
  201.     case MN_SELECTED:
  202.  
  203.         switch (msgbuf[4]) {
  204.         case MENUQUIT:
  205.  
  206.             prg_exit();
  207.             break;
  208.  
  209.         case MENUEDFN:
  210.  
  211. /*-------------------------------------------------------------------------
  212.  * Handling the EDIT FILENAME menu item...
  213.  *
  214.  * For a request to edit the field in the window, we must first ensure
  215.  * that our window is topped (an ACC could be topped).    If not, we do
  216.  * a wind_set() call to top it, because allowing editing in a background
  217.  * window goes against all GEM concepts.  After forcing the window to the
  218.  * top, we send an edit request back to ourselves, because our window
  219.  * doesn't really become topped until we receive back the corresponding
  220.  * redraw messages.
  221.  *
  222.  * We call menu_tnormal() to visually highlight the FILE title; if we're
  223.  * here because of a message we sent ourselves, the title won't already
  224.  * be highlighted.    If we're here because of a genuine menu selection
  225.  * by the user, it doesn't hurt to do the call anyway.
  226.  *
  227.  * If our window is topped, we call form_do() to handle the editing.  A
  228.  * nasty side effect of form_do() is that it will visually SELECT the
  229.  * edit field when the user hits return, so we immediately de-select it.
  230.  *
  231.  * Before starting the edit dialog, we set the ob_flags value for the
  232.  * filename edit field to EDITABLE, EXIT, and DEFAULT.    This allows the
  233.  * user to type in text and hit <CR> (a natural action), and the <CR>
  234.  * causes an exit from form_do() processing because of the DEFAULT flag
  235.  * on the edit field.  (What, you thought only buttons could be DEFAULT?)
  236.  * When the edit is done, we reset the ob_flags for the edit field.
  237.  *-----------------------------------------------------------------------*/
  238.  
  239.             menu_tnormal(menutree, MENUFILE, FALSE);
  240.             wind_get(0, WF_TOP, &top_window, &dmy, &dmy, &dmy);
  241.             if (wi_handle != top_window) {
  242.                 wind_set(wi_handle, WF_TOP, 0L, 0L);
  243.                 send_edmsg();
  244.             } else {
  245.                 wind_update(BEG_UPDATE);
  246.                 ptree[WINDTEFN].ob_flags |=  (EDITABLE|EXIT|DEFAULT);
  247.                 form_do(ptree, WINDTEFN);
  248.                 winx_get(wi_handle, WF_WORKXYWH, &t1);
  249.                 objc_change(ptree, WINDTEFN, 0, t1, NORMAL, TRUE);
  250.                 ptree[WINDTEFN].ob_flags &= ~(EDITABLE|EXIT|DEFAULT);
  251.                 wind_update(END_UPDATE);
  252.             }
  253.             break;
  254.         }
  255.         menu_tnormal(menutree, msgbuf[3], TRUE);
  256.         break;
  257.  
  258.     case WM_CLOSED:
  259.  
  260.         prg_exit();
  261.         break;
  262.  
  263.     case WM_TOPPED:
  264.     case WM_NEWTOP:
  265.  
  266.         wind_set(msgbuf[3], WF_TOP, 0L, 0L);
  267.         break;
  268.         
  269.     case WM_REDRAW:
  270.  
  271.         do_redraw(msgbuf[3], ptree, &msgbuf[4]);
  272.         break;
  273.  
  274.     case WM_MOVED:
  275.     case WM_SIZED:
  276.  
  277. /*-------------------------------------------------------------------------
  278.  * Handling SIZED and MOVED window requests...
  279.  *
  280.  * AES has given us the window outside dimensions of the user's mouse
  281.  * activity with the window controls, convert to workarea dimensions.
  282.  *
  283.  * Reposition the object tree at the proper x/y to match the window.
  284.  * Use rc_intersect() to ensure that a re-size operation does not exceed
  285.  *